/********************************************************************************
 * Project Name		[JavaSE_Fundamentals]
 * File Name     	[PrivateAccess.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 反射 - 私有属性访问(将任意一个对象中所有的String类型的成员变量所对应字符串内容中的b改为a)
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public class PrivateAccess {

	/**
	 * 转换方法
	 * 
	 * @param classType
	 *            待转换对象的类的类型
	 * @param convertObject
	 *            待转换的对象
	 * @throws Exception
	 */
	public static void convertString(Class<?> classType, Object convertObject) throws Exception {
		Field[] fields = classType.getDeclaredFields();
		for (Field field : fields) {
			if (field.getType() == String.class) {
				field.setAccessible(true);// 将属性设为可访问的(包括私有属性)
				System.out.println("该属性" + field.getName() + "是字符串并开始转换!");
				String fieldValue = (String) field.get(convertObject); // 获得属性值
				String newFieldValue = "";
				for (int i = 0; i < fieldValue.length(); i++) {
					char c = fieldValue.charAt(i);
					if (c == 'b') {
						newFieldValue += 'a';
					} else {
						newFieldValue += c;
					}
				}
				System.out.println("New filed value = " + newFieldValue);
				field.set(convertObject, newFieldValue);// 设置属性值
			} else {
				System.out.println("该属性" + field.getName() + "不是字符串");
			}
		}
	}

	/**
	 * 访问私有方法
	 * 
	 * @throws Exception
	 */
	public static void accessPrivateMethod(Class<?> classType) throws Exception {
		Object invokeObject = classType.newInstance();
		Method method = classType.getDeclaredMethod("sayHello", new Class[] { String.class });
		if (method != null) {
			method.setAccessible(true);
			method.invoke(invokeObject, new Object[] { "Sean" });

		}
	}

	public static void main(String[] args) {
		ObjectDemo demo = new ObjectDemo();
		try {
			System.out.println("转换前: " + demo);
			convertString(ObjectDemo.class, demo);
			System.out.println("转换后: " + demo);

			System.out.println();
			System.out.println("访问私有方法");
			accessPrivateMethod(ObjectDemo.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

/**
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 *
 */
@SuppressWarnings("unused")
class ObjectDemo {

	private String str1 = "ball";
	private int i = 10;
	private String str2 = "basketball";

	/**
	 * 重写的toString()方法
	 * 
	 * @return ObjectDemo实例的字符串表示
	 */
	@Override
	public String toString() {
		return "ObjectDemo [str1=" + str1 + ", str2=" + str2 + "]";
	}

	private void sayHello(String name) {
		System.out.println("Hello " + name + "!");
	}
}